#include "stdafx.h"
#include "CanProtocol.h"
#include "CanLib/canlib.h"
#include "GlobalVariable.h"

CCanProtocol::CCanProtocol(void)
{
	CANStatus.IfCanThreadRunning = FALSE;
	CANStatus.IfCMDSend =  FALSE;
	CANStatus.IfConnect =  FALSE;
	CANStatus.IfUnlock =  FALSE;
	CANStatus.IfDAQMod =  FALSE;
	CANStatus.IfWinThreadRunning =  FALSE;
	CANStatus.IfDisplayAllDTO =  FALSE;
	CANStatus.IfDataProcThreadRunning =  FALSE;
	CANStatus.CMD = 0;
	CANStatus.CanSndID = 0x733;
	CANStatus.CanRcvID = 0x734;
	CANStatus.FailCount = 0;
	CANStatus.CurAddress = 0;
	CANStatus.CTR = 0;

	//rSignal.flag = canMSG_EXT;
	//sSignal.flag = canMSG_EXT;

	m_canHandle  = -1 ;
	m_canBitRate =  BAUD_500K;
	m_IfCanBusOn = FALSE;

	//memset(sSignal.data,0,8); 
	//memset(rSignal.data,0,8); 

	memset(&sXlEvent, 0, sizeof(sXlEvent));
	sXlEvent.tag                 = XL_TRANSMIT_MSG;
	sXlEvent.tagData.msg.dlc     = 8;
	sXlEvent.tagData.msg.flags   = 0;

	memset(&rXlEvent, 0, sizeof(rXlEvent));
	rXlEvent.tag                 = XL_RECEIVE_MSG;
	rXlEvent.tagData.msg.dlc     = 8;
	rXlEvent.tagData.msg.flags   = 0;
}

CCanProtocol::~CCanProtocol(void)
{
}



#ifdef _CANCASE
bool  CCanProtocol::canStart(void)
{
	XLstatus      xlStatus;
	unsigned long  bitrate =  500000;
	xlStatus = m_func.CANGoOnBus(bitrate);

	if (!xlStatus) 
	{
		printf("can bus on!\n");
		return TRUE;

	}
	printf("can initial failed!\n");
	return FALSE;
}

bool CCanProtocol::canStop(void)
{

	XLstatus xlStatus;

	xlStatus = m_func.CANGoOffBus();
	if (!xlStatus) 
	{
		printf("can bus off!\n");
		return  TRUE;
	}
    
	return   FALSE;	
}

BYTE CCanProtocol::CMD_SEND(DWORD sID, XLevent& sXlEvent, int channel)
{
	XLstatus  xlStatus;
	sXlEvent.tagData.msg.id      = sID;

	xlStatus = m_func.CANSend(sXlEvent, channel );

	if ( xlStatus ==  XL_SUCCESS)
	{
		printf("0x%X SEND: %02X %02X %02X %02X %02X %02X %02X %02X \n",
			sID,
			sXlEvent.tagData.msg.data[0],
			sXlEvent.tagData.msg.data[1],
			sXlEvent.tagData.msg.data[2],
			sXlEvent.tagData.msg.data[3],
			sXlEvent.tagData.msg.data[4],
			sXlEvent.tagData.msg.data[5],
			sXlEvent.tagData.msg.data[6],
			sXlEvent.tagData.msg.data[7]);
		return 0;
	}

	return  0xff;
}


BYTE CCanProtocol::CMD_RECV(DWORD rID, XLevent& rXlEvent)
{

	int  overloap = 10;
	unsigned int    msgsrx = 1;

	while ( overloap-- )
	{
		WaitForSingleObject(m_func.m_gth.hMsgEvent,10);

		xlStatus = xlReceive(m_func.m_gth.xlPortHandle, &msgsrx, &rXlEvent);	

		if ( xlStatus ==  XL_SUCCESS)
		{
			if ( rID == rXlEvent.tagData.msg.id)
			{
				printf("0x%X RECV: %02X %02X %02X %02X %02X %02X %02X %02X \n",
					rXlEvent.tagData.msg.id,
					rXlEvent.tagData.msg.data[0],
					rXlEvent.tagData.msg.data[1],
					rXlEvent.tagData.msg.data[2],
					rXlEvent.tagData.msg.data[3],
					rXlEvent.tagData.msg.data[4],
					rXlEvent.tagData.msg.data[5],
					rXlEvent.tagData.msg.data[6],
					rXlEvent.tagData.msg.data[7]);
				return 0;
			}
		}
		
		Sleep(50);
	}

	printf("Receive failed!");
	return  0xff;

}

bool CCanProtocol::UDS_ECUReset(DWORD sID, DWORD rID, BYTE resetType)
{
	sXlEvent.tagData.msg.data[0] = 0x02;
	sXlEvent.tagData.msg.data[1] = SVID_ECUReset;
	sXlEvent.tagData.msg.data[2] = resetType;
	sXlEvent.tagData.msg.data[3] = 0;
	sXlEvent.tagData.msg.data[4] = 0;
	sXlEvent.tagData.msg.data[5] = 0;
	sXlEvent.tagData.msg.data[6] = 0;
	sXlEvent.tagData.msg.data[7] = 0;


	if ( 0x00 == CMD_SEND(sID,sXlEvent,0))
	{
		if (0x00 == CMD_RECV(rID,rXlEvent))
		{
			if ( 0x51 == rXlEvent.tagData.msg.data[1])
			{
				return true;
			}
		}
	}

	return false;
}

bool CCanProtocol::UDS_DiagnosticSessionControl(DWORD sID, DWORD rID, BYTE diagnosticSessionType)
{
	sXlEvent.tagData.msg.data[0] = 0x02;
	sXlEvent.tagData.msg.data[1] = SVID_SessionCtrl;
	sXlEvent.tagData.msg.data[2] = diagnosticSessionType;
	sXlEvent.tagData.msg.data[3] = 0;
	sXlEvent.tagData.msg.data[4] = 0;
	sXlEvent.tagData.msg.data[5] = 0;
	sXlEvent.tagData.msg.data[6] = 0;
	sXlEvent.tagData.msg.data[7] = 0;

	if ( 0x00 == CMD_SEND(sID,sXlEvent,0))
	{
		if (0x00 == CMD_RECV(rID,rXlEvent))
		{
			if ( 0x50 == rXlEvent.tagData.msg.data[1])
			{
				return true;
			}
		}
	}

	return false;
}

/*****************************************************************************************/
/*  the Control DTC Setting Service don't support    DTCSettingControlOptionRecord       */
/*****************************************************************************************/
bool CCanProtocol::UDS_ControlDTCSetting(DWORD sID, DWORD rID, BYTE DTCSettingType)
{
	sXlEvent.tagData.msg.data[0] = 0x02;
	sXlEvent.tagData.msg.data[1] = SVID_DTCSettingCtrl;
	sXlEvent.tagData.msg.data[2] = DTCSettingType; 
	sXlEvent.tagData.msg.data[3] = 0;
	sXlEvent.tagData.msg.data[4] = 0;
	sXlEvent.tagData.msg.data[5] = 0;
	sXlEvent.tagData.msg.data[6] = 0;
	sXlEvent.tagData.msg.data[7] = 0;

	if ( 0x00 == CMD_SEND(sID,sXlEvent,0))
	{
		if (0x00 == CMD_RECV(rID,rXlEvent))
		{
			if ( 0xC5 == rXlEvent.tagData.msg.data[1])
			{
				return true;
			}
		}
	}

	return false;
}

bool CCanProtocol::UDS_CommunicationControl(DWORD sID, DWORD rID, BYTE controlType,BYTE communicationType)
{
	sXlEvent.tagData.msg.data[0] = 0x03;
	sXlEvent.tagData.msg.data[1] = SVID_CommuCtrl;
	sXlEvent.tagData.msg.data[2] = controlType; 
	sXlEvent.tagData.msg.data[3] = communicationType;
	sXlEvent.tagData.msg.data[4] = 0;
	sXlEvent.tagData.msg.data[5] = 0;
	sXlEvent.tagData.msg.data[6] = 0;
	sXlEvent.tagData.msg.data[7] = 0;

	if ( 0x00 == CMD_SEND(sID,sXlEvent,0))
	{
		if (0x00 == CMD_RECV(rID,rXlEvent))
		{
			if ( 0x68 == rXlEvent.tagData.msg.data[1])
			{
				return true;
			}
		}
	}

	return false;
}

bool CCanProtocol::UDS_SecurityAccess(DWORD sID, DWORD rID, BYTE securityAccessType, BYTE securityAccessDataRecord[])
{
	sXlEvent.tagData.msg.data[1] = SVID_SecurityAccess;
	sXlEvent.tagData.msg.data[2] = securityAccessType; 
	if ( 0 != securityAccessType%2 )
	{
		sXlEvent.tagData.msg.data[0] = 0x02;
		sXlEvent.tagData.msg.data[3] = 0;
		sXlEvent.tagData.msg.data[4] = 0;
		sXlEvent.tagData.msg.data[5] = 0;
		sXlEvent.tagData.msg.data[6] = 0;
		sXlEvent.tagData.msg.data[7] = 0;
		if ( 0x00 == CMD_SEND(sID,sXlEvent,0) )
		{
			if ( 0x00 == CMD_RECV(rID,rXlEvent))
			{
				if ( 0x67 == rXlEvent.tagData.msg.data[1])
				{
					securityAccessDataRecord[0] = rXlEvent.tagData.msg.data[3];
					securityAccessDataRecord[1] = rXlEvent.tagData.msg.data[4];
					securityAccessDataRecord[2] = rXlEvent.tagData.msg.data[5];
					securityAccessDataRecord[3] = rXlEvent.tagData.msg.data[6];
					return true;
				}
			}
		}
	}
	else
	{
		if (securityAccessDataRecord == NULL)
		{
			return false;
		}
		sXlEvent.tagData.msg.data[0] = 0x06;
		sXlEvent.tagData.msg.data[3] = securityAccessDataRecord[0];
		sXlEvent.tagData.msg.data[4] = securityAccessDataRecord[1];
		sXlEvent.tagData.msg.data[5] = securityAccessDataRecord[2];
		sXlEvent.tagData.msg.data[6] = securityAccessDataRecord[3];
		sXlEvent.tagData.msg.data[7] = 0;
		if ( 0x00 == CMD_SEND(sID,sXlEvent,0) )
		{
			if ( 0x00 == CMD_RECV(rID,rXlEvent))
			{
				if ( 0x67 == rXlEvent.tagData.msg.data[1])
				{
					return true;
				}
			}
		}
	}

	return false;

}

bool CCanProtocol::UDS_RequestDownload(DWORD sID, DWORD rID, BYTE dataFormatIdentifier, BYTE addressAndLengthFormatIdentifier, BYTE* memoryAddress, BYTE* memorySize)
{
	bool    fail = 1;
	sXlEvent.tagData.msg.data[0] = 0x10;
	sXlEvent.tagData.msg.data[1] = 0x0b;
	sXlEvent.tagData.msg.data[2] = SVID_ReqDownload;
	sXlEvent.tagData.msg.data[3] = dataFormatIdentifier; 
	sXlEvent.tagData.msg.data[4] = addressAndLengthFormatIdentifier;
	sXlEvent.tagData.msg.data[5] = memoryAddress[0];
	sXlEvent.tagData.msg.data[6] = memoryAddress[1];
	sXlEvent.tagData.msg.data[7] = memoryAddress[2];

	if ( 0x00 == CMD_SEND(sID,sXlEvent,0) )
	{
		if ( 0x00 == CMD_RECV(rID,rXlEvent))
		{
			if ( 0x30 == rXlEvent.tagData.msg.data[0])
			{
				fail = 0;
			}
		}
	}

	if ( fail == 0 )
	{
		sXlEvent.tagData.msg.data[0] = 0x21;
		sXlEvent.tagData.msg.data[1] = memoryAddress[3];
		sXlEvent.tagData.msg.data[2] = memorySize[0];
		sXlEvent.tagData.msg.data[3] = memorySize[1]; 
		sXlEvent.tagData.msg.data[4] = memorySize[2];
		sXlEvent.tagData.msg.data[5] = memorySize[3];
		sXlEvent.tagData.msg.data[6] = 0;
		sXlEvent.tagData.msg.data[7] = 0;

		if ( 0x00 == CMD_SEND(sID,sXlEvent,0) )
		{
			if ( 0x00 == CMD_RECV(rID,rXlEvent))
			{
				if ( 0x74 == rXlEvent.tagData.msg.data[1])
				{
					return true;
				}
			}
		}
	}

	return false;

}


/********************************************************************************************************************/
/* this function don't check the number of data in transferRequestParameterRecord                                   */
/********************************************************************************************************************/
bool CCanProtocol::UDS_TransferData(DWORD sID, DWORD rID, WORD blockSequenceCounter, BYTE* transferRequestParameterRecord, WORD transferLength)
{
	bool fail = 1;
	/************************************************************************/
	/*  Single  Frame                                                       */
	/************************************************************************/
	if ( transferLength < 6 )
	{
		memset(sXlEvent.tagData.msg.data,0,8);

		sXlEvent.tagData.msg.data[0] = transferLength + 2;
		sXlEvent.tagData.msg.data[1] = SVID_TransferData;
		sXlEvent.tagData.msg.data[2] = blockSequenceCounter;

		for (int i = 0; i < transferLength; i++)
		{
			sXlEvent.tagData.msg.data[i+3] = transferRequestParameterRecord[i];
		}
		if ( 0x00 == CMD_SEND(sID,sXlEvent,0) )
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	/************************************************************************/
	/*  Consecutive  Frame                                                  */
	/************************************************************************/
	else
	{
		if (transferLength > 4095)
		{
			return false;
		}
		WORD wtemp = (transferLength | 0x1000) + 2; 
		sXlEvent.tagData.msg.data[0] = (BYTE)(wtemp >> 8);
		sXlEvent.tagData.msg.data[1] = (BYTE)wtemp;
		sXlEvent.tagData.msg.data[2] = SVID_TransferData;
		sXlEvent.tagData.msg.data[3] = blockSequenceCounter; 
		sXlEvent.tagData.msg.data[4] = transferRequestParameterRecord[0];
		sXlEvent.tagData.msg.data[5] = transferRequestParameterRecord[1];
		sXlEvent.tagData.msg.data[6] = transferRequestParameterRecord[2];
		sXlEvent.tagData.msg.data[7] = transferRequestParameterRecord[3];

		if ( 0x00 == CMD_SEND(sID,sXlEvent,0) )
		{
			if ( 0x00 == CMD_RECV(rID,rXlEvent) )
			{
				if ( 0x30 == rXlEvent.tagData.msg.data[0])
				{
					fail = 0;
				}
			}
		}
		if ( 0 == fail )
		{
			int leftCnt = transferLength - 4;
			BYTE  CFIndex = 0x21;
			while (( 0 == fail)&&( leftCnt > 0 ))
			{
				sXlEvent.tagData.msg.data[0] = CFIndex;
				for (int i = 1 ; i < 8; i++)
				{
					if ( leftCnt <= 0 )
					{
						sXlEvent.tagData.msg.data[i] = 0;
					} 
					else
					{
						sXlEvent.tagData.msg.data[i] = transferRequestParameterRecord[ transferLength - leftCnt ];
					}
					leftCnt--;
				}
				if ( 0x00 != CMD_SEND(sID,sXlEvent,0))
				{
					fail = 1;
				}
				CFIndex++;
				if ( CFIndex == 0x30)
				{
					CFIndex = 0x20;
				}
			}
			if ( 1 ==  fail )
			{
				return false;
			} 
			return true;
		}
	}

	return false;

}

bool CCanProtocol::UDS_RequestTransferExit(DWORD sID, DWORD rID, BYTE transferRequestParameterRecord)
{
	sXlEvent.tagData.msg.data[0] = 0x01;
	sXlEvent.tagData.msg.data[1] = SVID_ReqTransferExt;
	sXlEvent.tagData.msg.data[2] = 0;
	sXlEvent.tagData.msg.data[3] = 0; 
	sXlEvent.tagData.msg.data[4] = 0;
	sXlEvent.tagData.msg.data[5] = 0;
	sXlEvent.tagData.msg.data[6] = 0;
	sXlEvent.tagData.msg.data[7] = 0;

	if ( 0x00 == CMD_SEND(sID,sXlEvent,0) )
	{
		if ( 0x00 == CMD_RECV(rID,rXlEvent))
		{
			if ( 0x77 == rXlEvent.tagData.msg.data[1])
			{
				return true;
			}
		}
	}

	return false;

}


BYTE CCanProtocol::CMD_SEND_ARRAY(DWORD sID, DWORD rID, BYTE *array, WORD length, int channel)
{
	BYTE failcode = 0xff;
	sXlEvent.tagData.msg.id      = sID;
	memset(sXlEvent.tagData.msg.data,0,8);

	if (( length <= 0  ) || ( NULL == array ) || (length > 4095) )
	{
		return 0xfe;
	}
	if ( length < 8 )
	{
		for (int i = 0; i <length; i++)
		{
			sXlEvent.tagData.msg.data[i] = array[i];
		}
		return CMD_SEND(sID,sXlEvent,0);
	}
	else
	{
		WORD wtemp =  length ^ 0x1000 ; 
		sXlEvent.tagData.msg.data[0] = (BYTE)(wtemp >> 8);
		sXlEvent.tagData.msg.data[1] = (BYTE)wtemp;
		sXlEvent.tagData.msg.data[2] = array[0];
		sXlEvent.tagData.msg.data[3] = array[1]; 
		sXlEvent.tagData.msg.data[4] = array[2];
		sXlEvent.tagData.msg.data[5] = array[3];
		sXlEvent.tagData.msg.data[6] = array[4];
		sXlEvent.tagData.msg.data[7] = array[5];

		if ( 0x00 == CMD_SEND(sID,sXlEvent,0) )
		{
			if ( 0x00 == CMD_RECV(rID,rXlEvent) )
			{
				if ( 0x30 == rXlEvent.tagData.msg.data[0])
				{
					failcode = 0;
				}
			}
		}
		if (  0 == failcode )
		{
			int leftCnt = length - 6;
			BYTE  CFIndex = 0x21;
			while (( 0 == failcode)&&( leftCnt > 0 ))
			{
				sXlEvent.tagData.msg.data[0] = CFIndex;
				for (int i = 1 ; i < 8; i++)
				{
					if ( leftCnt <= 0 )
					{
						sXlEvent.tagData.msg.data[i] = 0;
					} 
					else
					{
						sXlEvent.tagData.msg.data[i] = array[ length - leftCnt ];
					}
					leftCnt--;
				}
				failcode = CMD_SEND(sID,sXlEvent,0);

				CFIndex++;
				if ( CFIndex == 0x30)
				{
					CFIndex = 0x20;
				}
			}
		}
		return failcode;
	}
}

#endif

#ifdef _KVASER
bool  CCanProtocol::canStart(void)
{
	canInitializeLibrary();
	m_canHandle = canOpenChannel(0, canWANT_EXTENDED);
	if (m_canHandle < 0) 
	{
		char msg[64];
		canGetErrorText((canStatus)m_canHandle, msg, sizeof(msg));
		printf("can initial failed!\n");
		return FALSE;
	}
	canSetBusParams(m_canHandle, m_canBitRate, 0, 0, 0, 0, 0);
	canSetBusOutputControl(m_canHandle, canDRIVER_NORMAL);
	canBusOn(m_canHandle);
	m_IfCanBusOn = TRUE;

	printf("can bus on!\n");

	//DWORD   time;
	//canIoCtl(m_canHandle,canIOCTL_GET_TIMER_SCALE,&time,sizeof(DWORD));

	return TRUE;
}

bool CCanProtocol::canStop(void)
{
	if(canBusOff(m_canHandle) == canOK)
	{
		if (canClose(m_canHandle) == canOK )
		{
			printf("can bus off!\n");
			return  TRUE;
		}
	}
	return   FALSE;	
}



BYTE CCanProtocol::CMD_SEND(DWORD sID, const CANSIGFRAME& sSignal)
{
	if (canWriteSync(m_canHandle, 10) == canOK)
	{
		if (canFlushReceiveQueue(m_canHandle) == canOK)
		{
			if((canWrite(m_canHandle, sID , (void *)sSignal.data, 8, canMSG_EXT) == canOK))
			{
				CString temp;
				temp.Format("0x%X SEND: %02X %02X %02X %02X %02X %02X %02X %02X \n",sID,sSignal.data[0],sSignal.data[1],sSignal.data[2],sSignal.data[3],sSignal.data[4],sSignal.data[5],sSignal.data[6],sSignal.data[7]);
				if (glv.m_start == true)
				{
					glv.m_logFile.WriteString(temp);
				}
				printf("0x%X SEND: %02X %02X %02X %02X %02X %02X %02X %02X \n",sID,sSignal.data[0],sSignal.data[1],sSignal.data[2],sSignal.data[3],sSignal.data[4],sSignal.data[5],sSignal.data[6],sSignal.data[7]);
				return 0x00;
			}
			else
			{
				return 0xff;
			}
		}
		else
		{
			return 0xff;
		}
	}
	else
	{
		return 0xff;
	}

}



BYTE CCanProtocol::CMD_RECV(DWORD rID, CANSIGFRAME& rSignal)
{
	if (canReadSyncSpecific(m_canHandle,  rID, 500)== canOK)
	{
		if(canReadSpecificSkip(m_canHandle,  rID, &rSignal.data, 
			&rSignal.dlc, &rSignal.flag, &rSignal.time)== canOK)
		{
			CString temp;
			temp.Format("0x%X RECV: %02X %02X %02X %02X %02X %02X %02X %02X \n",rID,rSignal.data[0],rSignal.data[1],rSignal.data[2],rSignal.data[3],rSignal.data[4],rSignal.data[5],rSignal.data[6],rSignal.data[7]);
			if (glv.m_start == true)
			{
				glv.m_logFile.WriteString(temp);
			}
			printf("0x%X RECV: %02X %02X %02X %02X %02X %02X %02X %02X \n",rID,rSignal.data[0],rSignal.data[1],rSignal.data[2],rSignal.data[3],rSignal.data[4],rSignal.data[5],rSignal.data[6],rSignal.data[7]);
			return  0x00;
		}
		return  0xff;
	}
	else
	{
		CString temp;
		temp.Format("0x%X RECEIVE: failed \n", rID);
		if (glv.m_start == true)
		{
			glv.m_logFile.WriteString(temp);
		}
		printf("0x%X RECEIVE: failed \n", rID);
		return 0xff;
	}
}


bool CCanProtocol::UDS_ECUReset(DWORD sID, DWORD rID, BYTE resetType)
{
	sSignal.data[0] = 0x02;
	sSignal.data[1] = SVID_ECUReset;
	sSignal.data[2] = resetType;
	sSignal.data[3] = 0;
	sSignal.data[4] = 0;
	sSignal.data[5] = 0;
	sSignal.data[6] = 0;
	sSignal.data[7] = 0;

	if ( 0x00 == CMD_SEND(sID,sSignal))
	{
		if (0x00 == CMD_RECV(rID,rSignal))
		{
			if ( 0x51 == rSignal.data[1])
			{
				return true;
			}
		}
	}

	return false;
}

bool CCanProtocol::UDS_DiagnosticSessionControl(DWORD sID, DWORD rID, BYTE diagnosticSessionType)
{
	sSignal.data[0] = 0x02;
	sSignal.data[1] = SVID_SessionCtrl;
	sSignal.data[2] = diagnosticSessionType;
	sSignal.data[3] = 0;
	sSignal.data[4] = 0;
	sSignal.data[5] = 0;
	sSignal.data[6] = 0;
	sSignal.data[7] = 0;

	if ( 0x00 == CMD_SEND(sID,sSignal))
	{
		if (0x00 == CMD_RECV(rID,rSignal))
		{
			if ( 0x50 == rSignal.data[1])
			{
				return true;
			}
		}
	}

	return false;
}


/*****************************************************************************************/
/*  the Control DTC Setting Service don't support    DTCSettingControlOptionRecord       */
/*****************************************************************************************/
bool CCanProtocol::UDS_ControlDTCSetting(DWORD sID, DWORD rID, BYTE DTCSettingType)
{
	sSignal.data[0] = 0x02;
	sSignal.data[1] = SVID_DTCSettingCtrl;
	sSignal.data[2] = DTCSettingType; 
	sSignal.data[3] = 0;
	sSignal.data[4] = 0;
	sSignal.data[5] = 0;
	sSignal.data[6] = 0;
	sSignal.data[7] = 0;

	if ( 0x00 == CMD_SEND(sID,sSignal))
	{
		if (0x00 == CMD_RECV(rID,rSignal))
		{
			if ( 0xC5 == rSignal.data[1])
			{
				return true;
			}
		}
	}

	return false;
}

bool CCanProtocol::UDS_CommunicationControl(DWORD sID, DWORD rID, BYTE controlType,BYTE communicationType)
{
	sSignal.data[0] = 0x03;
	sSignal.data[1] = SVID_CommuCtrl;
	sSignal.data[2] = controlType; 
	sSignal.data[3] = communicationType;
	sSignal.data[4] = 0;
	sSignal.data[5] = 0;
	sSignal.data[6] = 0;
	sSignal.data[7] = 0;

	if ( 0x00 == CMD_SEND(sID,sSignal))
	{
		if (0x00 == CMD_RECV(rID,rSignal))
		{
			if ( 0x68 == rSignal.data[1])
			{
				return true;
			}
		}
	}

	return false;
}

bool CCanProtocol::UDS_SecurityAccess(DWORD sID, DWORD rID, BYTE securityAccessType, BYTE securityAccessDataRecord[])
{
	sSignal.data[1] = SVID_SecurityAccess;
	sSignal.data[2] = securityAccessType; 
	if ( 0 != securityAccessType%2 )
	{
		sSignal.data[0] = 0x02;
		sSignal.data[3] = 0;
		sSignal.data[4] = 0;
		sSignal.data[5] = 0;
		sSignal.data[6] = 0;
		sSignal.data[7] = 0;
		if ( 0x00 == CMD_SEND(sID,sSignal) )
		{
			if ( 0x00 == CMD_RECV(rID,rSignal))
			{
				if ( 0x67 == rSignal.data[1])
				{
					securityAccessDataRecord[0] = rSignal.data[3];
					securityAccessDataRecord[1] = rSignal.data[4];
					securityAccessDataRecord[2] = rSignal.data[5];
					securityAccessDataRecord[3] = rSignal.data[6];
					return true;
				}
			}
		}
	}
	else
	{
		if (securityAccessDataRecord == NULL)
		{
			return false;
		}
		sSignal.data[0] = 0x06;
		sSignal.data[3] = securityAccessDataRecord[0];
		sSignal.data[4] = securityAccessDataRecord[1];
		sSignal.data[5] = securityAccessDataRecord[2];
		sSignal.data[6] = securityAccessDataRecord[3];
		sSignal.data[7] = 0;
		if ( 0x00 == CMD_SEND(sID,sSignal) )
		{
			if ( 0x00 == CMD_RECV(rID,rSignal))
			{
				if ( 0x67 == rSignal.data[1])
				{
					return true;
				}
			}
		}
	}

	return false;

}

bool CCanProtocol::UDS_RequestDownload(DWORD sID, DWORD rID, BYTE dataFormatIdentifier, BYTE addressAndLengthFormatIdentifier, BYTE* memoryAddress, BYTE* memorySize)
{
	bool    fail = 1;
	sSignal.data[0] = 0x10;
	sSignal.data[1] = 0x0b;
	sSignal.data[2] = SVID_ReqDownload;
	sSignal.data[3] = dataFormatIdentifier; 
	sSignal.data[4] = addressAndLengthFormatIdentifier;
	sSignal.data[5] = memoryAddress[0];
	sSignal.data[6] = memoryAddress[1];
	sSignal.data[7] = memoryAddress[2];

	if ( 0x00 == CMD_SEND(sID,sSignal) )
	{
		if ( 0x00 == CMD_RECV(rID,rSignal))
		{
			if ( 0x30 == rSignal.data[0])
			{
				fail = 0;
			}
		}
	}

	if ( fail == 0 )
	{
		sSignal.data[0] = 0x21;
		sSignal.data[1] = memoryAddress[3];
		sSignal.data[2] = memorySize[0];
		sSignal.data[3] = memorySize[1]; 
		sSignal.data[4] = memorySize[2];
		sSignal.data[5] = memorySize[3];
		sSignal.data[6] = 0;
		sSignal.data[7] = 0;

		if ( 0x00 == CMD_SEND(sID,sSignal) )
		{
			if ( 0x00 == CMD_RECV(rID,rSignal))
			{
				if ( 0x74 == rSignal.data[1])
				{
					return true;
				}
			}
		}
	}

	return false;

}


/********************************************************************************************************************/
/* this function don't check the number of data in transferRequestParameterRecord                                   */
/********************************************************************************************************************/
bool CCanProtocol::UDS_TransferData(DWORD sID, DWORD rID, WORD blockSequenceCounter, BYTE* transferRequestParameterRecord, WORD transferLength)
{
	bool fail = 1;
	/************************************************************************/
	/*  Single  Frame                                                       */
	/************************************************************************/
	if ( transferLength < 6 )
	{
		memset(sSignal.data,0,8);

		sSignal.data[0] = transferLength + 2;
		sSignal.data[1] = SVID_TransferData;
		sSignal.data[2] = blockSequenceCounter;

		for (int i = 0; i < transferLength; i++)
		{
			sSignal.data[i+3] = transferRequestParameterRecord[i];
		}
		if ( 0x00 == CMD_SEND(sID,sSignal) )
		{
			if ( 0x00 == CMD_RECV(rID,rSignal))
			{
				if ( 0x76 == rSignal.data[0])
				{
					return true;
				}
			}
		}
	}
	/************************************************************************/
	/*  Consecutive  Frame                                                  */
	/************************************************************************/
	else
	{
		if (transferLength > 4095)
		{
			return false;
		}
		WORD wtemp = (transferLength | 0x1000) + 2; 
		sSignal.data[0] = (BYTE)(wtemp >> 8);
		sSignal.data[1] = (BYTE)wtemp;
		sSignal.data[2] = SVID_TransferData;
		sSignal.data[3] = blockSequenceCounter; 
		sSignal.data[4] = transferRequestParameterRecord[0];
		sSignal.data[5] = transferRequestParameterRecord[1];
		sSignal.data[6] = transferRequestParameterRecord[2];
		sSignal.data[7] = transferRequestParameterRecord[3];

		if ( 0x00 == CMD_SEND(sID,sSignal) )
		{
			if ( 0x00 == CMD_RECV(rID,rSignal) )
			{
				if ( 0x30 == rSignal.data[0])
				{
					fail = 0;
				}
			}
		}
		if ( 0 == fail )
		{
			int leftCnt = transferLength - 4;
			BYTE  CFIndex = 0x21;
			while (( 0 == fail)& ( leftCnt > 0 ))
			{
				sSignal.data[0] = CFIndex;
				for (int i = 1 ; i < 8; i++)
				{
					if ( leftCnt <= 0 )
					{
						sSignal.data[i] = 0;
					} 
					else
					{
						sSignal.data[i] = transferRequestParameterRecord[ transferLength - leftCnt ];
					}
					leftCnt--;
				}
				if ( 0x00 != CMD_SEND(sID,sSignal))
				{
					fail = 1;
				}
				CFIndex++;
				if ( CFIndex == 0x30)
				{
					CFIndex = 0x20;
				}
			}
			if ( 1 ==  fail )
			{
				return false;
			} 
			return true;
		}
	}

	return false;

}

bool CCanProtocol::UDS_RequestTransferExit(DWORD sID, DWORD rID, BYTE transferRequestParameterRecord)
{
	sSignal.data[0] = 0x01;
	sSignal.data[1] = SVID_ReqTransferExt;
	sSignal.data[2] = 0;
	sSignal.data[3] = 0; 
	sSignal.data[4] = 0;
	sSignal.data[5] = 0;
	sSignal.data[6] = 0;
	sSignal.data[7] = 0;

	if ( 0x00 == CMD_SEND(sID,sSignal) )
	{
		if ( 0x00 == CMD_RECV(rID,rSignal))
		{
			if ( 0x77 == rSignal.data[1])
			{
				return true;
			}
		}
	}

	return false;

}
#endif

CANSIGFRAME::CANSIGFRAME(void){}
CANSIGFRAME::~CANSIGFRAME(void){}
CANSIGFRAME& CANSIGFRAME::operator=(CANSIGFRAME &cansig)
{
	for (int i = 0; i < 8; i++)
	{
		data[i] = cansig.data[i];
	}
	dlc = cansig.dlc;
	flag = cansig.flag;
	id = cansig.id;
	time = cansig.time;
	pData = cansig.pData;
	return *this;
}